from flask import Blueprint, jsonify, request
from flask_jwt_extended import jwt_required
from app.forms.system.role import RoleAdd, RoleEdit
from app.models import RoleModel, MenuModel
from app.exts import db
from utils import scalars_to_list, model_to_dict
from json import dumps, loads

role = Blueprint('role', __name__)


@role.get('/get/permission')
@jwt_required()
def role_get_permission():
    id = request.args.get('id')
    role_model = RoleModel.query.get(id)
    menu_ids = [m.id for m in role_model.menus]
    return jsonify(code=200, message='获取成功', data=menu_ids)


# 为身份分配权限
@role.post('/set/permission')
@jwt_required()
def role_set_permission():
    body = request.get_json()
    role_id = body.get('role_id')
    menu_ids = body.get('menu_ids')
    role_model = RoleModel.query.get(role_id)
    # 取出该身份所有分配的菜单权限，预删除
    menus_all_ids = [r_m_m.id for r_m_m in role_model.menus]
    # 取出所有关联的菜单，将其从身份关联中删除
    for m_id in menus_all_ids:
        m_model = MenuModel.query.get(m_id)
        role_model.menus.remove(m_model)
    # 将客服端传入的菜单 ids 关联于身份
    for menu_id in menu_ids:
        menu_model = MenuModel.query.get(menu_id)
        role_model.menus.append(menu_model)
    db.session.commit()
    return jsonify(code=200, message='权限设置成功')


@role.post('/add')
@jwt_required()
def role_add():
    body = request.get_json()
    role_add = RoleAdd(data=body)
    if not role_add.validate():
        # 只获取第一个字典的错误信息
        error_first = next(iter(role_add.errors.values()))[0]
        return jsonify(code=400, message=error_first)
    role_model = RoleModel(
        name=body.get('name'),
        code=body.get('code'),
        sort=body.get('sort'),
        status=body.get('status')
    )
    try:
        db.session.add(role_model)
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))
    return jsonify(code=200, message='添加成功')


@role.get('/list')
@jwt_required()
def role_list():
    page_number = request.args.get('page_number', default=1, type=int)
    page_size = request.args.get('page_size', default=10, type=int)
    name = request.args.get('name', default='', type=str)
    '''
    page: 获取当前第 n 页
    per_page: 每页显示 n 条数据
    '''
    role_model = RoleModel.query.filter(RoleModel.name.like(f'%{name}%')).order_by(RoleModel.sort).paginate(
        page=page_number,
        per_page=page_size,
        error_out=False
    )
    data = scalars_to_list(role_model.items)
    return jsonify(code=200, message='获取成功', data=data, total=role_model.total)


@role.delete('/remove')
@jwt_required()
def role_remove():
    body = request.get_json()
    ids = body.get('ids') or []
    role_model = RoleModel.query.filter(RoleModel.id.in_(ids)).all()
    for role in role_model:
        db.session.delete(role)

    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))
    return jsonify(code=200, message='删除成功')


@role.put('/edit')
@jwt_required()
def role_edit():
    body = request.get_json()
    role_edit = RoleEdit(data=body)
    if not role_edit.validate():
        error_first = next(iter(role_edit.errors.values()))[0]
        return jsonify(code=400, message=error_first)
    id = body.get('id')
    role_model = RoleModel.query.get(id)
    role_model.sort = body.get('sort')
    role_model.status = body.get('status')
    role_model.name = body.get('name')
    role_model.code = body.get('code')
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        db.session.flush()
        return jsonify(code=500, message=str(e))
    return jsonify(code=200, message='修改成功')
